package it.lovaex.scb.businesslogic;

import it.lovaex.scb.model.CartItem;
import it.lovaex.scb.model.IItem;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;

public class Cart {

	private ArrayList<CartItem> itemList;
	private BigDecimal threshold;
	private BigDecimal additionalRate;
	private BigDecimal rawTotal;
	private BigDecimal finalTotal;
	
	public Cart(BigDecimal threshold, BigDecimal additionalRate){
		itemList = new ArrayList<CartItem>();
		this.threshold = threshold;
		this.additionalRate = additionalRate;
		rawTotal = BigDecimal.valueOf(0);
		finalTotal = BigDecimal.valueOf(0);
	}
	
	public void empty(){
		itemList.clear();
	}
	
	public boolean isEmpty(){
		return itemList.isEmpty();
	}
	
	public void add(int quantity ,IItem item){
		itemList.add(new CartItem(quantity, item));
	}
	
	public BigDecimal getTotal(){
		rawTotal = BigDecimal.valueOf(0);
		for(CartItem item : itemList){
			rawTotal = rawTotal.add(getFinalPrice(item));
		}
		finalTotal = rawTotal;
		if(hasAdditionalDiscount())
			finalTotal = rawTotal.subtract(getAdditionalDiscount());
		return finalTotal.setScale(1, RoundingMode.CEILING).setScale(2);
	}
	
	@Override
	public String toString() {
		getTotal();
		StringBuilder builder = new StringBuilder();
		builder.append("\t\t\t|\tQuantity\t|\tUnitPrice\t|\tDiscount\t|\tFinal Price\t|\n");
		for (CartItem cartItem : itemList) {
			builder.append(cartItem.getDescription() + "\t| " + 
					cartItem.getQuantity() + "\t| " + 
					cartItem.getUnitPrice().setScale(2, RoundingMode.CEILING) + "\t| " + 
					cartItem.getDiscount().multiply(BigDecimal.valueOf(100)).setScale(0, RoundingMode.CEILING) + "%\t| " + 
					getFinalPrice(cartItem).setScale(2, RoundingMode.CEILING) + "\n");
		}
		if(hasAdditionalDiscount()){
			builder.append("GrossTotal\t\t\t\t\t\t\t" + rawTotal.setScale(2, RoundingMode.CEILING) + "\n");
			builder.append("VolumeDiscount\t\t\t\t" + additionalRate.multiply(BigDecimal.valueOf(100)).setScale(0, RoundingMode.DOWN) + "%\t" + rawTotal.subtract(finalTotal).setScale(2, RoundingMode.CEILING) + "\n");
		}
		builder.append("Total\t\t\t\t\t\t\t\t" + finalTotal.setScale(1, RoundingMode.CEILING).setScale(2));
		return builder.toString();
	}
	
	private boolean hasAdditionalDiscount(){
		return rawTotal.compareTo(threshold) > 0;
	}
	
	private BigDecimal getAdditionalDiscount(){
		return rawTotal.multiply(additionalRate);
	}
	
	private BigDecimal getFinalPrice(CartItem item) {
		BigDecimal result = BigDecimal.valueOf(item.getQuantity()).
				multiply(item.getUnitPrice()).
				multiply(
						BigDecimal.valueOf(1).
						subtract(item.getDiscount())
				);
		return result;
	}
	
}
